package logic

import (
	"errors"
	"fmt"
	"sort"
	"sync"
	"sync/atomic"
	"time"
)

type AllianceMember struct {
	Name       string
	JoinTime   time.Time
	Job        string
	Contribute int
}
type AllianceData struct {
	AllianceId   int
	AllianceName string
	CreateTime   time.Time

	ChairmanName string
	//MemberMap       map[string]*AllianceMember
	MemberMap sync.Map
	size      int32 // 这个安全map，不能计数  很烦

	Capacity    []*Item
	capaLock    sync.RWMutex
	ExpendTimes int32 // 扩充次数

}

func NewAllianceData(name string) *AllianceData {
	return &AllianceData{
		AllianceName: name,
		CreateTime:   time.Now(),
	}
}

func JoinAlliance(alliance *AllianceData, role *Role, job string) {
	member := &AllianceMember{
		Name:       role.Data.Name,
		JoinTime:   time.Now(),
		Contribute: 0,
		Job:        job,
	}
	alliance.MemberMap.Store(role.Data.Name, member)
	atomic.AddInt32(&alliance.size, 1)
	fmt.Println("加入了", alliance.size)
}
func (a *AllianceData) MemberSize() int32 {
	return a.size
}

func (a *AllianceData) Init() {
	// 初始化 成员名单
	//a.MemberMap = make(map[string]*AllianceMember)
	// 初始化仓库
	a.Capacity = make([]*Item, 30)
	for i, v := range AllianceItemInItPro {
		err := a.StoreItemIndex(i, v, 0)
		if err != nil {
			fmt.Println("ERR:公会仓库道具初始化发生问题:" + err.Error())
			return
		}
	}
	fmt.Println("初始化完成")
}

func (a *AllianceData) Dismiss() {
	// 初始化 成员名单，
	a.MemberMap.Range(func(_, v interface{}) bool {
		role, err := GameServer.GetOnlineMgr().Get(v.(*AllianceMember).Name)
		if err == nil {
			role.OutAlliance()
			role.Connection.SendBuffMsg(0, []byte("你的公会解散了"))
		} else {
			roleData, err := Ds.GetRoleByName(v.(*AllianceMember).Name)
			if err == nil {
				roleData.AllianceName = ""
			}
		}
		return true
	})

	//for _, v := range a.MemberMap {
	//	role, err := GameServer.GetOnlineMgr().Get(v.Name)
	//	if err == nil {
	//		role.OutAlliance()
	//		role.Connection.SendBuffMsg(0, []byte("你的公会解散了"))
	//	} else {
	//		roleData, err := Ds.GetRoleByName(v.Name)
	//		if err == nil {
	//			roleData.AllianceName = ""
	//		}
	//	}
	//}
	Ds.RemoveAlliance(a.AllianceName)
}

func (a *AllianceData) ExpandCapacity() error {
	a.capaLock.Lock()
	defer a.capaLock.Unlock()

	a.ExpendTimes += 1
	size := len(a.Capacity)
	size += 10
	old := a.Capacity
	a.Capacity = make([]*Item, size)
	copy(a.Capacity, old)
	return nil
}

func (a *AllianceData) ListItem() []*Item {
	a.capaLock.RLock()
	defer a.capaLock.RUnlock()
	return a.Capacity
}

func (a *AllianceData) StoreItem(itemList ...Item) error {
	return nil
}

func (a *AllianceData) StoreItemIndex(itemId int32, itemNum int32, index int) error {
	a.capaLock.Lock()
	defer a.capaLock.Unlock()

	itemConfig, ok := ItemConfig[itemId]
	if !ok {
		return errors.New("配置中未找到道具")
	}
	size := len(a.Capacity)
	if index >= size || index < 0 {
		return errors.New("index 太大了")
	}
	if itemNum <= 0 {
		return errors.New("数量有误")
	}
	cycle := false
	for i := index; ; i++ {
		if i >= size {
			i -= size
			cycle = true
		}
		if cycle && i == index {
			return errors.New("仓库满了，" + fmt.Sprint(itemId) + "还有" + fmt.Sprint(itemNum) + " 个 没放进去")
		}
		positionIt := a.Capacity[i]
		if positionIt == nil || positionIt.Id == itemId {
			if positionIt == nil {
				positionIt = &Item{
					Name: itemConfig.Name,
					Type: itemConfig.Type,
					Id:   itemConfig.Id,
				}
			}
			a.Capacity[i] = positionIt
			leftSpace := 5 - positionIt.Num
			if leftSpace >= itemNum {
				positionIt.Num += itemNum
				return nil
			} else if leftSpace > 0 {
				positionIt.Num = 5
				itemNum -= leftSpace
			}
		}
	}
}
func (a *AllianceData) DeleteItemIndex(index int) error {
	a.capaLock.Lock()
	defer a.capaLock.Unlock()

	size := len(a.Capacity)
	if index >= size {
		return errors.New("index 太大了")
	}
	a.Capacity[index] = nil
	return nil
}

func (a *AllianceData) CleanUpItem() {
	a.capaLock.Lock()
	defer a.capaLock.Unlock()

	temp := make(map[int32]*Item)
	for _, v := range a.Capacity {
		if v == nil {
			continue
		}
		i, ok := temp[v.Id]
		if ok {
			i.Num += v.Num
		} else {
			temp[v.Id] = v
		}
	}
	newCapa := make([]*Item, len(a.Capacity))
	i := 0
	for _, itemCount := range temp {
		for {
			item := &Item{
				Id:   itemCount.Id,
				Name: itemCount.Name,
				Type: itemCount.Type,
			}
			newCapa[i] = item
			i++
			if itemCount.Num <= 5 {
				item.Num = itemCount.Num
				break
			} else {
				item.Num = 5
				itemCount.Num -= 5
			}

		}
	}
	a.Capacity = newCapa
	sort.Sort(a)
}

// Len  排序相关的三个方法
func (a *AllianceData) Len() int { // 重写 Len() 方法
	return len(a.Capacity)
}
func (a *AllianceData) Swap(i, j int) { // 重写 Swap() 方法
	a.Capacity[i], a.Capacity[j] = a.Capacity[j], a.Capacity[i]
}
func (a *AllianceData) Less(i, j int) bool { // 重写 Less() 方法
	right := a.Capacity[i]
	left := a.Capacity[j]
	// 有空的时候的比较
	if left == nil && right == nil {
		return false
	} else if left == nil {
		return true
	} else if right == nil {
		return false
	}

	// 类型小在前面，数量大的在前面
	if left.Type > right.Type {
		return true
	} else if left.Type == right.Type {
		if left.Num < right.Num {
			return true
		}
	}

	return false
}
